﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace ServiceCore.Tool.JD_Pay
{
    public static class DictionaryExtensionMethodClass
    {
        /// <summary>
        /// SortedDictionary的扩展方法，将键和值添加或替换到字典中：如果不存在，则添加；存在，则替换
        /// </summary>
        public static SortedDictionary<TKey, TValue> AddOrPeplace<TKey, TValue>(this SortedDictionary<TKey, TValue> dict, TKey key, TValue value)
        {
            dict[key] = value;
            return dict;
        }

        /// <summary>
        /// SortedDictionary的扩展方法，根据key获取对应的值，如果不存在，返回null
        /// </summary>
        public static TValue getVaule<TKey, TValue>(this SortedDictionary<TKey, TValue> dict, TKey key)
        {
            if (dict.ContainsKey(key))
            {
                return dict[key];
            }
            return default(TValue);
        }

        /// <summary>
        /// Dictionary的扩展方法，将键和值添加或替换到字典中：如果不存在，则添加；存在，则替换
        /// </summary>
        public static Dictionary<TKey, TValue> AddOrPeplace<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
        {
            dict[key] = value;
            return dict;
        }
    }
    public class JD_Tool
    {
        private static readonly Encoding encoding = Encoding.UTF8;
        public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
        {
            string formDataBoundary = Guid.NewGuid().ToString();
            string contentType = "multipart/form-data; boundary=" + formDataBoundary;
            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);
            return PostForm(postUrl, userAgent, contentType, formData);
        }
        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
        {
            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

            if (request == null)
            {
                throw new NullReferenceException("request is not a http request");
            }
            request.Method = "POST";
            request.ContentType = contentType;
            request.UserAgent = userAgent;
            request.CookieContainer = new CookieContainer();
            request.ContentLength = formData.Length;
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            return request.GetResponse() as HttpWebResponse;
        }
        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
        {
            Stream formDataStream = new System.IO.MemoryStream();
            bool needsCLRF = false;

            foreach (var param in postParameters)
            {
                if (needsCLRF)
                    formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

                needsCLRF = true;

                if (param.Value is FileParameter)
                {
                    FileParameter fileToUpload = (FileParameter)param.Value;
                    string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                        boundary,
                        param.Key,
                        fileToUpload.FileName ?? param.Key,
                        fileToUpload.ContentType ?? "application/octet-stream");

                    formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));
                    formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
                }
                else
                {
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                        boundary,
                        param.Key,
                        param.Value);
                    formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
                }
            }
            string footer = "\r\n--" + boundary + "--\r\n";
            formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));
            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }

        public static string post(string Url, SortedDictionary<String, String> parameters)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "POST";
                request.Proxy = null;
                request.Timeout = 10000;
                if (Url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                }
                request.ContentType = "application/x-www-form-urlencoded";
                //如果需要POST数据 
                if (!(parameters == null || parameters.Count == 0))
                {
                    StringBuilder buffer = new StringBuilder();
                    int i = 0;
                    foreach (string key in parameters.Keys)
                    {
                        String ss = System.Web.HttpUtility.UrlEncode(parameters[key]);//用UrlEncode进行编码
                        if (i > 0)
                        {
                            buffer.AppendFormat("&{0}={1}", key, ss);
                        }
                        else
                        {
                            buffer.AppendFormat("{0}={1}", key, ss);
                        }
                        i++;
                    }
                    if (buffer.Length > 0)
                    {
                        byte[] data = Encoding.UTF8.GetBytes(buffer.ToString());
                        request.ContentLength = data.Length;
                        using (Stream myRequestStream = request.GetRequestStream())
                        {
                            myRequestStream.Write(data, 0, data.Length);
                            myRequestStream.Close();
                        }

                    }
                }
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                using (Stream myResponseStream = response.GetResponseStream())
                {
                    StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
                    string retString = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    myResponseStream.Close();
                    return retString;
                }
            }
            catch (Exception e)
            {
                throw e;
            }

        }
        //该方法用于验证服务器证书是否合法，当然可以直接返回true来表示验证永远通过。服务器证书具体内容在参数certificate中。可根据个人需求验证
        //该方法在request.GetResponse()时触发
        private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            /*
            //获取本地存储的服务器安全证书
            X509Certificate cer = X509Certificate.CreateFromCertFile(RequestUtil.getFilePath() + "jdpay.cer");
            //比较服务器证书的合法
            if (cer.GetSerialNumberString().Equals(certificate.GetSerialNumberString()))
            {
                return true;
            }   
            return false;
            */
            return true;
        }

        public static FileParameter FileToByte2(string Url)
        {
            WebClient webClient = new WebClient();
            byte[] fileContentByte = webClient.DownloadData(Url);
            FileParameter File = new FileParameter(fileContentByte, Url);
            return File;
        }
        #region Des3
        private const int MAX_MSG_LENGTH = 16 * 1024;
        private static byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        public static String Des3EncryptECB(byte[] key, String data)
        {
            byte[] resultByte = initResultByteArray(data);
            System.Diagnostics.Debug.WriteLine("补位后的byte数组长度:" + resultByte.Length);
            System.Diagnostics.Debug.WriteLine("补位后数据HEX表示:" + byteToHexStr(resultByte));
            System.Diagnostics.Debug.WriteLine("秘钥HEX表示:" + byteToHexStr(key));
            System.Diagnostics.Debug.WriteLine("秘钥长度:" + key.Length);
            byte[] desdata = Des3EncodeECB(key, iv, resultByte);

            System.Diagnostics.Debug.WriteLine("秘钥长度:" + desdata.Length);
            return byteToHexStr(desdata);
        }
        public static String Des3DecryptECB(byte[] key, String data)
        {
            //byte[] dataByte = Encoding.UTF8.GetBytes(data);
            byte[] hexSourceData = hex2byte(data);
            byte[] unDesResult = Des3DecodeECB(key, iv, hexSourceData);
            byte[] dataSizeByte = new byte[4];
            dataSizeByte[0] = unDesResult[0];
            dataSizeByte[1] = unDesResult[1];
            dataSizeByte[2] = unDesResult[2];
            dataSizeByte[3] = unDesResult[3];
            int dsb = byteArrayToInt(dataSizeByte, 0);
            if (dsb > MAX_MSG_LENGTH)
            {
                throw new Exception("msg over MAX_MSG_LENGTH or msg error");
            }
            byte[] tempData = new byte[dsb];
            for (int i = 0; i < dsb; i++)
            {
                tempData[i] = unDesResult[4 + i];
            }
            System.Diagnostics.Debug.WriteLine("--------原数据:" + data);
            String hexStr = byteToHexStr(tempData);
            String str = hex2bin(hexStr);
            System.Diagnostics.Debug.WriteLine("--------解密后数据:" + str);
            return str;
        }


        private static byte[] initResultByteArray(String data)
        {
            byte[] source = Encoding.UTF8.GetBytes(data);
            System.Diagnostics.Debug.WriteLine("原数据:" + data);
            System.Diagnostics.Debug.WriteLine("原数据byte长度:" + source.Length);
            System.Diagnostics.Debug.WriteLine("原数据HEX表示:" + byteToHexStr(source));
            int merchantData = source.Length;
            int x = (merchantData + 4) % 8;
            int y = (x == 0) ? 0 : (8 - x);
            System.Diagnostics.Debug.WriteLine("需要补位 :" + y);
            byte[] resultByte = new byte[merchantData + 4 + y];
            resultByte[0] = (byte)((merchantData >> 24) & 0xFF);
            resultByte[1] = (byte)((merchantData >> 16) & 0xFF);
            resultByte[2] = (byte)((merchantData >> 8) & 0xFF);
            resultByte[3] = (byte)(merchantData & 0xFF);
            //4.填充补位数据
            for (int i = 0; i < merchantData; i++)
            {
                resultByte[4 + i] = source[i];
            }
            for (int i = 0; i < y; i++)
            {
                resultByte[merchantData + 4 + i] = 0x00;
            }

            return resultByte;
        }
        public static byte[] hex2byte(String b)
        {
            if ((b.Length % 2) != 0)
            {
                throw new Exception("长度不是偶数");
            }
            byte[] b2 = new byte[b.Length / 2];
            for (int n = 0; n < b.Length; n += 2)
            {
                //byte[] sub = new byte[2];
                //Array.Copy(b,n,sub,0,2);
                //String item = byteToHexStr(sub);
                String item = b.Substring(n, 2);
                // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个进制字节
                b2[n / 2] = (byte)Convert.ToInt32(item, 16);
            }
            b = null;
            return b2;
        }
        private static int byteArrayToInt(byte[] b, int offset)
        {
            int value = 0;
            for (int i = 0; i < 4; i++)
            {
                int shift = (4 - 1 - i) * 8;
                value += (b[i + offset] & 0x000000FF) << shift;//往高位游
            }
            return value;
        }

        public static String hex2bin(String hex)
        {
            String digital = "0123456789abcdef";
            char[] hex2char = hex.ToCharArray();
            byte[] bytes = new byte[hex.Length / 2];
            int temp;
            for (int i = 0; i < bytes.Length; i++)
            {
                temp = digital.IndexOf(hex2char[2 * i]) * 16;
                temp += digital.IndexOf(hex2char[2 * i + 1]);
                bytes[i] = (byte)(temp & 0xff);
            }

            return Encoding.UTF8.GetString(bytes);
        }

        public static String bytesToString(byte[] src)
        {
            String hexString = "0123456789ABCDEF";
            StringBuilder stringBuilder = new StringBuilder("");
            if (src == null || src.Length <= 0)
            {
                return null;
            }
            for (int i = 0; i < src.Length; i++)
            {
                int v = src[i] & 0xFF;
                String hv = Convert.ToString(v, 16);
                if (hv.Length < 2)
                {
                    stringBuilder.Append(0);
                }
                stringBuilder.Append(hv);
            }
            String srcStr = stringBuilder.ToString();
            //ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
            // 将每2位16进制整数组装成一个字节
            // for (int i = 0; i<bytes.length(); i += 2)
            //     baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1))));

            char[] chars = srcStr.ToCharArray();
            byte[] bytes = new byte[srcStr.Length / 2];
            int temp;
            for (int i = 0; i < bytes.Length; i++)
            {
                temp = hexString.IndexOf(chars[2 * i]) << 4;
                temp += hexString.IndexOf(chars[2 * i + 1]);
                bytes[i] = (byte)(temp & 0xff);
            }

            return Encoding.UTF8.GetString(bytes);
        }

        #region ECB模式
        /// <summary>
        /// DES3 ECB模式加密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV(当模式为ECB时，IV无用)</param>
        /// <param name="str">明文的byte数组</param>
        /// <returns>密文的byte数组</returns>
        private static byte[] Des3EncodeECB(byte[] key, byte[] iv, byte[] data)
        {
            try
            {
                MemoryStream mStream = new MemoryStream();
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.ECB;
                tdsp.Padding = PaddingMode.Zeros;
                //tdsp.Padding = PaddingMode.None;
                CryptoStream cStream = new CryptoStream(mStream, tdsp.CreateEncryptor(key, iv), CryptoStreamMode.Write);
                cStream.Write(data, 0, data.Length);
                cStream.FlushFinalBlock();
                byte[] ret = mStream.ToArray();
                cStream.Close();
                mStream.Close();
                return ret;
            }
            catch (CryptographicException e)
            {
                System.Diagnostics.Debug.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        /// <summary>
        /// DES3 ECB模式解密
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="iv">IV(当模式为ECB时，IV无用)</param>
        /// <param name="str">密文的byte数组</param>
        /// <returns>明文的byte数组</returns>
        private static byte[] Des3DecodeECB(byte[] key, byte[] iv, byte[] data)
        {
            try
            {
                MemoryStream msDecrypt = new MemoryStream(data);
                TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
                tdsp.Mode = CipherMode.ECB;
                tdsp.Padding = PaddingMode.Zeros;
                //tdsp.Padding = PaddingMode.None;
                CryptoStream csDecrypt = new CryptoStream(msDecrypt, tdsp.CreateDecryptor(key, iv), CryptoStreamMode.Read);
                byte[] fromEncrypt = new byte[data.Length];
                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
                return fromEncrypt;
            }
            catch (CryptographicException e)
            {
                System.Diagnostics.Debug.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }
        #endregion
        //将数组转换成16进制字符串
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr.ToLower();
        }
        #endregion
        #region SignHelper
        /// <summary>
        /// 数据签名
        /// </summary>
        /// <param name="dic">请求数据</param>
        /// <param name="algorithm">签名方式 SHA，SHA-256</param>
        /// <param name="salt">签名秘钥</param>
        /// <returns>签名后数据</returns>
        public static string sign(string data)
        { 
            byte[] sourceByte = Encoding.UTF8.GetBytes(data);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] cryByte = md5.ComputeHash(sourceByte);
            return byteToHexStr(cryByte);
        }

        /// <summary>
        /// sign值
        /// </summary>
        /// <param name="model"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        public static string GetSign(SortedDictionary<string, string> model, string secretKey)
        {
            //排序后组合成加密字符串
            string CryptoText = string.Empty;
            foreach (var d in model)
            {
                //空值不参与签名
                if (!string.IsNullOrEmpty(d.Value))
                {
                    CryptoText += string.Format("{0}={1}&", d.Key, d.Value.Trim('"'));
                }
            }
            CryptoText = CryptoText.Trim('&') + secretKey;

            return MD5Encrypt(CryptoText).ToLower();
        }
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>
        public static string MD5Encrypt(string strText)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strText);
            bytes = md5.ComputeHash(bytes);
            md5.Clear();

            string ret = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
            }

            return ret.PadLeft(32, '0');
        }
        #endregion

        /// <summary>
        /// 与JAVA互通的3DES加密
        /// </summary>
        /// <param name="inStr">待加密字符串</param>
        /// <param name="deskey">密钥</param>
        /// <returns></returns>
        public static string UGetDes3EncryptStr(string inStr, string deskey)
        {
            byte[] key = Convert.FromBase64String(deskey);
            byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };      //当模式为ECB时，IV无用
            byte[] data = Encoding.UTF8.GetBytes(inStr);

            byte[] str1 = Des3EncodeECB(key, iv, data);
            return parseByte2HexStr(str1).ToLower();
        }

        /// <summary>
        /// 与JAVA互通的3DES解密
        /// </summary>
        /// <param name="inStr">待解密字符串</param>
        /// <param name="deskey">密钥</param>
        /// <returns></returns>
        public static string UGetDes3DecryptStr(string inStr, string deskey)
        {
            byte[] key = Convert.FromBase64String(deskey);
            byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };      //当模式为ECB时，IV无用

            byte[] str3 =  parseHexStr2Byte(inStr);
            byte[] str2 =  Des3DecodeECB(key, iv, str3);
            return Encoding.UTF8.GetString(str2).Replace("\0", "");
        }
        /// <summary>
        /// 10进制byte数组转换为16进制字符串
        /// </summary>
        /// <param name="buf"></param>
        /// <returns></returns>
        public static String parseByte2HexStr(byte[] buf)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < buf.Length; i++)
            {

                String hex = String.Format("{0:X}", buf[i] & 0xFF);
                if (hex.Length == 1)
                {
                    hex = '0' + hex;
                }
                sb.Append(hex);
            }
            return sb.ToString();
        }
        /// <summary>
        /// 16进制字符串转换为10进制byte数组
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public static byte[] parseHexStr2Byte(String hexStr)
        {
            if (hexStr.Length < 1)
                return null;
            byte[] result = new byte[hexStr.Length / 2];
            for (int i = 0; i < hexStr.Length / 2; i++)
            {
                int high = Convert.ToInt32(hexStr.Substring(i * 2, 1), 16);
                int low = Convert.ToInt32(hexStr.Substring(i * 2 + 1, 1), 16);

                result[i] = (byte)(high * 16 + low);
            }
            return result;
        }
        /// <summary>
        /// HttpClient实现Post请求
        /// </summary>
        public static string Post(string url, string data, HttpClientHandler handler = null)
        {
            if (handler == null)
                handler = new HttpClientHandler();

            using (var client = new HttpClient(handler))
            {
                //使用StringContent做HttpContent
                var content = new StringContent(data);
                content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
                //await异步等待回应
                var task = client.PostAsync(url, content);

                task.Wait();
                var response = task.Result;

                //确保HTTP成功状态值
                response.EnsureSuccessStatusCode();

                //await异步读取最后的JSON
                var resultTask = response.Content.ReadAsStringAsync();
                resultTask.Wait();
                return resultTask.Result;
            }
        } 
    }
    public class Jd_Post
    {
        private JD_data_model Temp_model = new JD_data_model();
        private Request_Params RequestParams = new Request_Params();
        private string Ulr = "";
        /// <summary>
        /// 统一调用接口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="subdata"></param>
        /// <param name="user_model"></param>
        public static void Start_JD_Api<T>(T subdata, JD_data_model user_model, string systemId, Action<Request_Params> action)
        {
            SortedDictionary<string, string> sub_dic = new SortedDictionary<string, string>();
            foreach (var item in subdata.GetType().GetProperties())
            {
                if (item.Name == "Request_URL")
                {
                    continue;
                }
                if (item.GetValue(subdata) != null)
                {
                    sub_dic.AddOrPeplace(item.Name, item.GetValue(subdata).ToString());
                }
            }
            string sign = JD_Tool.GetSign(sub_dic, user_model.mdKey);
            string rawData = Newtonsoft.Json.JsonConvert.SerializeObject(sub_dic);
            string cipherJson = JD_PAY.Security.UGetDes3EncryptStr(rawData, user_model.desKey);
            Request_Params result = new Request_Params()
            {
                merchantNo = user_model.merchantNo,
                cipherJson = cipherJson,
                sign = sign,
                systemId = systemId
            };
            action(result);
        }
        /// <summary>
        /// 统一调用接口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="subdata"></param>
        /// <param name="user_model"></param>
        public Jd_Post Start_JD_Api<T>(T subdata, JD_data_model user_model, string systemId) where T : JD_Api_Base_Params
        {
            SortedDictionary<string, string> sub_dic = new SortedDictionary<string, string>();
            foreach (var item in subdata.GetType().GetProperties())
            {
                if (item.Name == "Request_URL")
                {
                    continue;
                }
                if (item.GetValue(subdata) != null)
                {
                    sub_dic.AddOrPeplace(item.Name, item.GetValue(subdata).ToString());
                }
            }
            string sign = JD_Tool.GetSign(sub_dic, user_model.mdKey);
            string rawData = Newtonsoft.Json.JsonConvert.SerializeObject(sub_dic);
            string cipherJson = JD_PAY.Security.UGetDes3EncryptStr(rawData, user_model.desKey);
            Request_Params result = new Request_Params()
            {
                merchantNo = user_model.merchantNo,
                cipherJson = cipherJson,
                sign = sign,
                systemId = systemId
            };
            RequestParams = result;
            Temp_model = user_model;
            Ulr = subdata.Request_URL;
            return this;
        }
        /// <summary>
        /// 进行一次请求
        /// </summary>
        public void Start_Post<T>(Action<bool, string, string, T> action) where T : new()
        {
            string respon = JD_Tool.Post(Ulr, Newtonsoft.Json.JsonConvert.SerializeObject(RequestParams));
            var PostResultItem = Newtonsoft.Json.JsonConvert.DeserializeObject<Response_Result>(respon);
            if (!PostResultItem.success)
            {
                action(PostResultItem.success, PostResultItem.errCode, PostResultItem.errCodeDes, new T());
            }
            else
            {
                string result = JD_PAY.Security.UGetDes3DecryptStr(PostResultItem.cipherJson, Temp_model.desKey);
                action(PostResultItem.success, PostResultItem.errCode, PostResultItem.errCodeDes, Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result));
            }
        } 
        /// <summary>
        /// 单独解析接收数据
        /// </summary>
        public static void Start_Notify<T>(Stream InputStream, Func<string, JD_data_model> func, Action<Response_Result, T,string> action,ref string Rdata) where T : new()
        {
            try
            { 
                StreamReader reader = new StreamReader(InputStream);
                string data = reader.ReadToEnd();
                Rdata = data;
                var PostResultItem = Newtonsoft.Json.JsonConvert.DeserializeObject<Response_Result>(data); 
                if (!PostResultItem.success)
                {
                    action(PostResultItem, new T(), "");
                }
                else
                {
                    var shopdata = func(PostResultItem.merchantNo);
                    if (shopdata == null)
                    {
                        PostResultItem.errCode = "-1";
                        PostResultItem.errCodeDes = "未能获取商户资料";
                        action(PostResultItem, new T(),"");
                    }
                    if (string.IsNullOrWhiteSpace(shopdata.desKey))
                    {
                        PostResultItem.errCode = "-1";
                        PostResultItem.errCodeDes = "商户未开通";
                    }
                    string result = JD_PAY.Security.UGetDes3DecryptStr(PostResultItem.cipherJson, shopdata.desKey);
                    action(PostResultItem, Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result), result);
                }
            }
            catch (Exception ex)
            {
                action(new Response_Result() { errCode = "-1", success = false, errCodeDes = "发生异常=>" + ex.ToString() }, new T(), "");
            }
        }
    }
}
